﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

using Liolikas.GameObjects;
using Liolikas.GameBoard;
using Liolikas.GameMenu;
using Liolikas.Scores;

namespace Liolikas.LiolikasGame
{
    class Game
    {
        static int MONSTER_SPEED = 10;
        public static int FRAME_RATE = 60;
        public  Boolean isOver { get; set; }
        DateTime begin;
        static Game game;
        static Random seedGenerator;
        Thread renderer;
        int ms = 1000 / FRAME_RATE;
        List<Character> monsters { get; set; }
        Boolean loadingMessageIsShown;

        Game (){
            isOver = false;
            seedGenerator = new Random(DateTime.Now.Millisecond);
            Board.GetBoard().InitBoard();
            monsters = new List<Character>();
            loadingMessageIsShown = false;
        }

        public void AddMonsters(int number){
            for (int i = 0; i < number; i++)
            {
                //1 - as horizontal  border occupies 1 line of console
                monsters.Add(new Abalys(0, 0, MONSTER_SPEED));
                monsters.Add(new Abalys(0, Board.BOARD_WIDTH - 2, MONSTER_SPEED));
                monsters.Add(new Abalys(Board.BOARD_HEIGHT - 1, 0, MONSTER_SPEED));
                monsters.Add(new Abalys(Board.BOARD_HEIGHT - 1, Board.BOARD_WIDTH - 2, MONSTER_SPEED));
            }
        }

        public void StartGame(){
            PlayerChar.GetPlayerChar().model = PlayerChar.STANDART_MODEL;
            loadingMessageIsShown = true;
            Renderer.InitBoard();
            Game.GetGame().isOver = false;

            
            ResetChars();
            ResetGame();

        }

        private void ResetChars(){
            PlayerChar.GetPlayerChar().Reset();
            foreach (Character m in monsters) m.Reset();
        }

        public void ResetGame()
        {
            InitAnimation();
            
            begin = DateTime.UtcNow;
        }

        public int GetSeed()
        {
            return seedGenerator.Next();
        }

        public void InitAnimation()
        {   
            renderer = new Thread(() =>
            {
                while (!Game.GetGame().isOver)
                {
                    GetNextFrame();
                    Thread.Sleep(ms);
                   
                }
                this.EndGame();
            });
            renderer.Start();
            
        }

        private void GetNextFrame()
        {
            if (loadingMessageIsShown)
            {
                Renderer.HideLoadingMessage();
                loadingMessageIsShown = false;
            }

            //Move Liolikas
            Renderer.MovePlayerChar();

            //Move monsters
            foreach (Character monster in Game.GetGame().monsters)
                Renderer.MoveObject(monster);

            //update score
            Renderer.UpdateScore(GetScore());
        }

        public static Game GetGame()
        {
            if (game == null) game = new Game();
            return game;
        }

        public void EndGame()
        {
          int gameScore = Game.GetGame().GetScore();
          Console.Beep(3000, 1000);
          Boolean isHighScore = HighScore.GetHightScore().NewScore(gameScore, DateTime.Now.ToShortDateString());
          Renderer.GameOver(gameScore, isHighScore);
         
          Console.ReadLine();
          Menu.GetMenu().ShowMenu();
        }

        internal int GetScore()
        {
            return (int)(DateTime.UtcNow - begin).TotalSeconds;
        }

    }

    
}
